using ReaderB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Weight.Base;

namespace  RFCard
{
    public class RfidDevice : ICard
    {
        private int mDeviceHandle ;
        private byte mComAddr;
        private int mCmdResult; //所有执行指令的返回值

        private string  mScanTime;  //询查命令最大响应时间

        private static List<string> mCompareCarNo = new List<string>();
        
        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        public ResultEntity Init()
        {
            return ResultEntity.Success("RFID设备 不需要初始化SDK");
        }

       /// <summary>
       /// 打开设备
       /// </summary>
       /// <param name="entity"></param>
       /// <returns></returns>
        public ResultEntity Open(OpenEntity entity)
        {
            var res = ResultEntity.Default();
            try
            {
                mComAddr = Convert.ToByte("FF", 16);
                byte budrate = GetBudrate(entity.BaudRate);
                int comPort=0;
                int result = StaticClassReaderB.OpenComPort(entity.Port, ref mComAddr, budrate, ref comPort);
                mDeviceHandle = comPort;
              
                if (result == 0)
                {
                   ResultEntity versionResult=  GetDeviceInfo();
                    if ((mCmdResult == 0x35) || (mCmdResult == 0x30))
                    {
                        res = ResultEntity.Error("RFID设备 串口通讯错误!");
                        StaticClassReaderB.CloseSpecComPort(mDeviceHandle);
                    }
                    else
                    {
                       ResultEntity modelResult =  SetWorkModel(budrate,entity.Power, mDeviceHandle);
                        res = ResultEntity.Success(versionResult.Message+"设置工作模式:"+modelResult.Message);
                    }
                }
                else
                {
                    res = ResultEntity.Error("RFId设备 打开设备失败,原因:"+GetReturnCodeDesc(result));
                }
            }
            catch(Exception ex)
            {
                res = ResultEntity.Error("RFID设备 打开异常，异常信息:"+ex.Message+","+ex.StackTrace);
            }

            return res;
        }

        /// <summary>
        /// 清卡
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public ResultEntity Clear(ClearParamEntity entity)
        {
            return ResultEntity.Success("RFID设备 不支持清卡操作!");
        }

        /// <summary>
        /// 关闭电子标签设备
        /// </summary>
        /// <returns></returns>
        public ResultEntity Close()
        {
            ResultEntity result = ResultEntity.Default();
            try
            {
               int res =  StaticClassReaderB.CloseSpecComPort(mDeviceHandle);
                if(res == 0)
                {
                    result = ResultEntity.Success("RFID设备 关闭成功");
                }
                else
                {
                    result = ResultEntity.Error("RFID设备 关闭失败");
                }
            }
            catch (Exception ex)
            {
                result = ResultEntity.Error("RFID设备 关闭异常，异常信息:"+ex.Message+","+ex.StackTrace);
            }
            return result;
        }

        /// <summary>
        /// 获取卡号
        /// </summary>
        /// <returns></returns>
        public ResultEntity<ResultValEntity> GetCardNo()
        {
            ResultValEntity entity = new ResultValEntity();
            var res = ResultEntity<ResultValEntity>.Default(entity,"");
            try
            {
                byte[] buffer = new byte[512];
                int ValidDatalength=0;
               int  fCmdRet = StaticClassReaderB.ReadActiveModeData(buffer, ref ValidDatalength, mDeviceHandle);
                if (fCmdRet == 0)
                {
                    string content = string.Empty;
                    foreach (byte b in buffer)
                    {
                        content += Convert.ToString(b, 16).PadLeft(2, '0');
                    }

                    StringBuilder contentBuider = new StringBuilder();

                    bool isRightCardNo = false;
                    long ls_temp = 0;
                    int count = (content.Length - content.Length % 16) / 16;
                    for (int i = 0; i < count; i = i + 16)
                    {
                        ls_temp = Convert.ToInt64(content.Substring(i + 2, 14), 16);
                        string ls_long = "";
                        //if(ls_temp.ToString().Length -5 >=10)
                        //{
                           
                        //}
                        ls_long = ls_temp.ToString("D15").Substring(5, 10);
                        if (ls_long.Length > 0)
                        {
                            if (contentBuider.Length > 1000)
                            {
                                contentBuider.Clear();
                            }
                            contentBuider.Append(ls_long + ",");
                        }
                        if (mCompareCarNo.Contains(ls_long))
                        {
                            entity.val = content;
                            res = ResultEntity< ResultValEntity>.Success(entity, ls_long);
                            isRightCardNo = true;
                            break;
                        }
                        else
                        {
                            if (!contentBuider.ToString().Contains("无效卡号:" + ls_long + ","))
                            {
                                contentBuider.Append("无效卡号:" + ls_long + ",");
                            }
                        }
                    }

                    if(!isRightCardNo)
                    {
                        res = ResultEntity<ResultValEntity>.Success(entity, content);
                    }
                }
                else
                {
                    res= ResultEntity<ResultValEntity>.Error(entity, "RFID设备 获取卡号失败，原因:"+ GetReturnCodeDesc(fCmdRet));
                }
            }
            catch (Exception ex)
            {
                res= ResultEntity<ResultValEntity>.Error(entity, "RFID设备 获取卡号异常,异常信息:"+ex.Message+","+ex.StackTrace);
            }

            return res;
        }
       

        /// <summary>
        /// 读卡
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public ResultEntity<ResultValEntity> Read(ReadParamEntity entity)
        {
            ResultValEntity val = new ResultValEntity();
            return ResultEntity< ResultValEntity>.Success(val,"RFID设备 不支持读卡操作!");
        }

        /// <summary>
        /// 写卡
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public ResultEntity Write(WriteParamEntity entity)
        {
            return ResultEntity.Success( "RFID设备 不支持写卡操作!");
        }

        /// <summary>
        /// 获得设置波特率所对应的变量
        /// </summary>
        /// <param name="baud">波特率</param>
        /// <returns></returns>
        private byte GetBudrate(int baud)
        {
            switch (baud)
            {
                case 9600:
                    return 0;
                case 19200:
                    return 1;
                case 38400:
                    return 2;
                case 56000:
                    return 4;
                case 57600:
                    return 5;
                case 115200:
                    return 6;
                default:
                    return 5;
            }
        }


        /// <summary>
        /// 获取设备信息
        /// </summary>
        /// <returns></returns>
        public ResultEntity GetDeviceInfo()
        {
            var result = ResultEntity.Default();
            try
            {
                byte[] TrType = new byte[2];
                byte[] VersionInfo = new byte[2];
                byte ReaderType = 0;
                byte ScanTime = 0;
                byte dmaxfre = 0;
                byte dminfre = 0;
                byte powerdBm = 0;
                byte FreBand = 0;
                mCmdResult = StaticClassReaderB.GetReaderInformation(ref mComAddr, VersionInfo, ref ReaderType, TrType, ref dmaxfre, ref dminfre, ref powerdBm, ref ScanTime, mDeviceHandle);
                if (mCmdResult == 0)
                {
                    StringBuilder infoBuider = new StringBuilder();
                    infoBuider.Append("版本:").Append( Convert.ToString(VersionInfo[0], 10).PadLeft(2, '0') + "." + Convert.ToString(VersionInfo[1], 10).PadLeft(2, '0')).Append("; \r\n");
                    infoBuider.Append("功率:").Append(powerdBm).Append("; \r\n")
                        .Append("地址:").Append(mComAddr).Append("; \r\n");
                    mScanTime = Convert.ToString(ScanTime, 10).PadLeft(2, '0') + "*100ms";
                    infoBuider.Append("询查命令最大响应时间:").Append(mScanTime).Append("; \r\n");
                    
                    FreBand = Convert.ToByte(((dmaxfre & 0xc0) >> 4) | (dminfre >> 6));
                    double fdminfre = 0;
                    double fdmaxfre = 0;
                    switch (FreBand)
                    {
                        case 0:
                            {
                                infoBuider.Append("频段:").Append("User band; \r\n");
                                fdminfre = 902.6 + (dminfre & 0x3F) * 0.4;
                                fdmaxfre = 902.6 + (dmaxfre & 0x3F) * 0.4;
                            }
                            break;
                        case 1:
                            {
                                infoBuider.Append("频段:").Append("Chinese band2; \r\n");
                                fdminfre = 920.125 + (dminfre & 0x3F) * 0.25;
                                fdmaxfre = 920.125 + (dmaxfre & 0x3F) * 0.25;
                            }
                            break;
                        case 2:
                            {
                                infoBuider.Append("频段:").Append("US band; \r\n");
                                fdminfre = 902.75 + (dminfre & 0x3F) * 0.5;
                                fdmaxfre = 902.75 + (dmaxfre & 0x3F) * 0.5;
                            }
                            break;
                        case 3:
                            {
                                infoBuider.Append("频段:").Append("Korean band; \r\n");
                                fdminfre = 917.1 + (dminfre & 0x3F) * 0.2;
                                fdmaxfre = 917.1 + (dmaxfre & 0x3F) * 0.2;
                            }
                            break;
                        case 4:
                            {
                                infoBuider.Append("频段:").Append("EU band; \r\n");
                                fdminfre = 865.1 + (dminfre & 0x3F) * 0.2;
                                fdmaxfre = 865.1 + (dmaxfre & 0x3F) * 0.2;
                            }
                            break;
                    }


                    infoBuider.Append("最低频率:").Append( Convert.ToString(fdminfre) + "MHz \r\n");
                    infoBuider.Append("最高频率:").Append(Convert.ToString(fdmaxfre) + "MHz \r\n");
                    if (ReaderType == 0x09)
                        infoBuider.Append("型号:UHFReader18 \r\n");
                    if ((TrType[0] & 0x02) == 0x02) //第二个字节低第四位代表支持的协议“ISO/IEC 15693”
                    {
                        infoBuider.Append("支持协议: 支持 ISO180006B/EPCC1G2 \r\n" );
                    }
                    else
                    {
                        infoBuider.Append("支持协议: 不支持 ISO180006B/EPCC1G2 \r\n");
                    }

                    result = ResultEntity.Success(infoBuider.ToString());
                }
                else
                {
                    result = ResultEntity.Error("RFID设备 读取设备信息失败，原因:" + GetReturnCodeDesc(mCmdResult));
                }
            }
            catch (Exception ex)
            {
                result = ResultEntity.Error("RFID设备 获取设备信息异常，异常信息:"+ex.Message+","+ex.StackTrace);
            }

            return result;
           
        }

        /// <summary>
        /// 设置读写器参数
        /// </summary>
        /// <param name="comAdr">读写器地址,范围00~FF</param>
        /// <param name="baud">读写器波特率</param>
        /// <param name="powerdmW">读写器功率,范围1~30</param>
        /// <param name="workmode">读写器工作模式.当前设定为主动模式,即值为1</param>
        /// <param name="fOpenComIndex">当前串口索引号</param>
        /// <returns>成功返回true失败返回false</returns>
        public ResultEntity SetWorkModel(int baud, int power, int fOpenComIndex)
        {
            var result = ResultEntity.Default();
            if (baud <= 0)
            {
                return ResultEntity.Error("RFID设备 参数波特率错误,波特率不能小于1，当前波特率为:"+baud);
            }
            try
            {
                //功率
                byte powerDbm = Convert.ToByte(power);
                int  fCmdRet = StaticClassReaderB.SetPowerDbm(ref mComAddr, powerDbm, fOpenComIndex);

                //工作模式
                byte[] Parameter = new byte[6];

                int Reader_bit0 = 0;//EPCC1-G2为0,ISO18000-6B为1
                int Reader_bit1 = 1;//RS232/RS485和SYRIS485输出为1,韦根输出为0
                int Reader_bit2 = 0;//开启蜂鸣器为0,关闭蜂鸣器为1
                int Reader_bit3 = 0;//起始地址选择,字地址为0,字节地址为1
                int Reader_bit4 = 0;//SYRIS485输出为1,其他为0
                Parameter[0] = Convert.ToByte(1);//应答模式为0,主动模式为1,触发模式(低电平)为2,触发模式(高电平)为3
                Parameter[1] = Convert.ToByte(Reader_bit0 * 1 + Reader_bit1 * 2 + Reader_bit2 * 4 + Reader_bit3 * 8 + Reader_bit4 * 16);
                Parameter[2] = 1;//保留区为0,EPC取为1,TID区为2,用户区为3,多张询查为4,单张询查为5,EAS为6
                Parameter[3] = Convert.ToByte("00", 16);//起始字地址
                Parameter[4] = Convert.ToByte(1);//读取字节数
                Parameter[5] = Convert.ToByte(0); //单张标签过滤时间单位S

                fCmdRet = StaticClassReaderB.SetWorkMode(ref mComAddr, Parameter, fOpenComIndex);
                if (fCmdRet == 0)
                {
                    result = ResultEntity.Success("RFID设备 设置工作模式成功!");
                }
                else
                {
                    result = ResultEntity.Success("RFID设备 设置工作模式失败,原因:"+ GetReturnCodeDesc(fCmdRet));
                }

            }
            catch(Exception ex)
            {
                result = ResultEntity.Error("RFID设备 设置工作模式异常，异常信息:"+ex.Message+","+ex.StackTrace);
            }
            return result;
        }

        private string GetReturnCodeDesc(int cmdRet)
        {
            switch (cmdRet)
            {
                case 0x00:
                    return "操作成功";
                case 0x01:
                    return "询查时间结束前返回";
                case 0x02:
                    return "指定的询查时间溢出";
                case 0x03:
                    return "本条消息之后，还有消息";
                case 0x04:
                    return "读写模块存储空间已满";
                case 0x05:
                    return "访问密码错误";
                case 0x09:
                    return "销毁密码错误";
                case 0x0a:
                    return "销毁密码不能为全0";
                case 0x0b:
                    return "电子标签不支持该命令";
                case 0x0c:
                    return "对该命令，访问密码不能为全0";
                case 0x0d:
                    return "电子标签已经被设置了读保护，不能再次设置";
                case 0x0e:
                    return "电子标签没有被设置读保护，不需要解锁";
                case 0x10:
                    return "有字节空间被锁定，写入失败";
                case 0x11:
                    return "不能锁定";
                case 0x12:
                    return "已经锁定，不能再次锁定";
                case 0x13:
                    return "参数保存失败,但设置的值在读写模块断电前有效";
                case 0x14:
                    return "无法调整";
                case 0x15:
                    return "询查时间结束前返回";
                case 0x16:
                    return "指定的询查时间溢出";
                case 0x17:
                    return "本条消息之后，还有消息";
                case 0x18:
                    return "读写模块存储空间已满";
                case 0x19:
                    return "电子不支持该命令或者访问密码不能为0";
                case 0xFA:
                    return "有电子标签，但通信不畅，无法操作";
                case 0xFB:
                    return "无电子标签可操作";
                case 0xFC:
                    return "电子标签返回错误代码";
                case 0xFD:
                    return "命令长度错误";
                case 0xFE:
                    return "不合法的命令";
                case 0xFF:
                    return "参数错误";
                case 0x30:
                    return "通讯错误";
                case 0x31:
                    return "CRC校验错误";
                case 0x32:
                    return "返回数据长度有错误";
                case 0x33:
                    return "通讯繁忙，设备正在执行其他指令";
                case 0x34:
                    return "繁忙，指令正在执行";
                case 0x35:
                    return "端口已打开";
                case 0x36:
                    return "端口已关闭";
                case 0x37:
                    return "无效句柄";
                case 0x38:
                    return "无效端口";
                case 0xEE:
                    return "返回指令错误";
                default:
                    return "";
            }
        }
        private string GetErrorCodeDesc(int cmdRet)
        {
            switch (cmdRet)
            {
                case 0x00:
                    return "其它错误";
                case 0x03:
                    return "存储器超限或不被支持的PC值";
                case 0x04:
                    return "存储器锁定";
                case 0x0b:
                    return "电源不足";
                case 0x0f:
                    return "非特定错误";
                default:
                    return "";
            }
        }

        /// <summary>
        /// 设置对比卡号
        /// </summary>
        /// <param name="cardNos"></param>
        public void SetComparison(List<string> cardNos)
        {
            mCompareCarNo = cardNos;
        }
    }
}


